<template>
  <div>
    <el-form
      :ref="formConf.ref != null ? formConf.ref : formConfBak.ref"
      :model="model"
      :rules="formConf.rules != null ? formConf.rules : formConfBak.rules"
      :label-width="
        formConf.labelWidth != null
          ? formConf.labelWidth
          : formConfBak.labelWidth
      "
      :label-position="
        formConf.labelPosition != null
          ? formConf.labelPosition
          : formConfBak.labelPosition
      "
      :inline="formConf.inline != null ? formConf.inline : formConfBak.inline"
      :label-suffix="
        formConf.labelSuffix != null
          ? formConf.labelSuffix
          : formConfBak.labelSuffix
      "
      :hide-required-asterisk="
        formConf.hideRequiredAsterisk != null
          ? formConf.hideRequiredAsterisk
          : formConfBak.hideRequiredAsterisk
      "
      :show-message="
        formConf.showMessage != null
          ? formConf.showMessage
          : formConfBak.showMessage
      "
      :inline-message="
        formConf.inlineMessage != null
          ? formConf.inlineMessage
          : formConfBak.inlineMessage
      "
      :status-icon="
        formConf.statusIcon != null
          ? formConf.statusIcon
          : formConfBak.statusIcon
      "
      :validate-on-rule-change="
        formConf.validateOnRuleChange != null
          ? formConf.validateOnRuleChange
          : formConfBak.validateOnRuleChange
      "
      :size="formConf.size != null ? formConf.size : formConfBak.size"
      :disabled="
        formConf.disabled != null ? formConf.disabled : formConfBak.disabled
      "
      @validate="formValidate"
    >
      <el-form-item
        v-for="(elCol, dIndex) in layout"
        v-show="
          elCol.elFormItem.isShow == null ? true : elCol.elFormItem.isShow
        "
        :key="dIndex"
        :ref="elCol.elFormItem.ref"
        :prop="elCol.elFormItem.prop"
        :label="elCol.elFormItem.label"
        :label-width="elCol.elFormItem.labelWidth"
        :required="elCol.elFormItem.required"
        :rules="elCol.elFormItem.rules"
        :error="elCol.elFormItem.error"
        :show-message="elCol.elFormItem.showMessage"
        :inline-message="elCol.elFormItem.inlineMessage"
        :size="elCol.elFormItem.size"
      >
        <template #error="{error}">
          <slot name="error" :error="error"></slot>
        </template>
        <el-input
          v-if="
            elCol.elFormItem.type == 'input' ||
              elCol.elFormItem.type == 'textarea'
          "
          v-model="model[elCol.elFormItem.prop]"
          :style="elCol.elFormItem.style"
          :placeholder="
            elCol.elFormItem.placeholder != null
              ? elCol.elFormItem.placeholder
              : '请输入' + elCol.elFormItem.label
          "
          :disabled="elCol.elFormItem.disabled"
          :maxlength="elCol.elFormItem.maxlength"
          :show-word-limit="elCol.elFormItem.showWordLimit"
          :autosize="elCol.elFormItem.autosize"
          :type="elCol.elFormItem.type"
          :clearable="
            elCol.elFormItem.clearable != null
              ? elCol.elFormItem.clearable
              : formConfBak.clearable
          "
        />
        <el-select
          v-else-if="elCol.elFormItem.type == 'select'"
          v-model="model[elCol.elFormItem.prop]"
          :style="elCol.elFormItem.style"
          :disabled="elCol.elFormItem.disabled"
          :placeholder="
            elCol.elFormItem.placeholder != null
              ? elCol.elFormItem.placeholder
              : '请选择' + elCol.elFormItem.label
          "
          :clearable="
            elCol.elFormItem.clearable != null
              ? elCol.elFormItem.clearable
              : formConfBak.clearable
          "
        >
          <el-option
            v-for="(option, index) in elCol.elFormItem.options"
            :key="index"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
        <el-radio-group
          v-else-if="elCol.elFormItem.type == 'radio'"
          v-model="model[elCol.elFormItem.prop]"
          :style="elCol.elFormItem.style"
          :disabled="elCol.elFormItem.disabled"
          :clearable="
            elCol.elFormItem.clearable != null
              ? elCol.elFormItem.clearable
              : formConfBak.clearable
          "
        >
          <el-radio
            v-for="option in elCol.elFormItem.options"
            :key="option.value"
            :label="option.value"
          >
            {{ option.label }}
          </el-radio>
        </el-radio-group>
        <el-date-picker
          v-else-if="
            elCol.elFormItem.type == 'datetime' ||
              elCol.elFormItem.type == 'datetimerange'
          "
          v-model="model[elCol.elFormItem.prop]"
          :style="elCol.elFormItem.style"
          :disabled="elCol.elFormItem.disabled"
          :picker-options="elCol.elFormItem.pickerOptions"
          :default-time="elCol.elFormItem.defaultTime"
          :placeholder="
            elCol.elFormItem.placeholder != null
              ? elCol.elFormItem.placeholder
              : '请选择' + elCol.elFormItem.label
          "
          :format="
            elCol.elFormItem.format == null
              ? 'yyyy-MM-dd HH:mm:ss'
              : elCol.elFormItem.format
          "
          :value-format="
            elCol.elFormItem.valueFormat == null
              ? 'yyyy-MM-dd HH:mm:ss'
              : elCol.elFormItem.valueFormat
          "
          :type="elCol.elFormItem.type"
          :start-placeholder="
            elCol.elFormItem.startPlaceholder != null
              ? elCol.elFormItem.startPlaceholder
              : formConfBak.dateTime.startPlaceholder
          "
          :end-placeholder="
            elCol.elFormItem.endPlaceholder != null
              ? elCol.elFormItem.endPlaceholder
              : formConfBak.dateTime.endPlaceholder
          "
          :range-separator="
            elCol.elFormItem.rangeSeparator != null
              ? elCol.elFormItem.rangeSeparator
              : formConfBak.dateTime.rangeSeparator
          "
          :clearable="
            elCol.elFormItem.clearable != null
              ? elCol.elFormItem.clearable
              : formConfBak.clearable
          "
          align="right"
        />
        <el-cascader
          v-else-if="elCol.elFormItem.type == 'cascader'"
          v-model="model[elCol.elFormItem.prop]"
          :style="elCol.elFormItem.style"
          :placeholder="
            elCol.elFormItem.placeholder != null
              ? elCol.elFormItem.placeholder
              : '请选择' + elCol.elFormItem.label
          "
          :disabled="elCol.elFormItem.disabled"
          :options="elCol.elFormItem.options"
          :props="elCol.elFormItem.props"
          :clearable="
            elCol.elFormItem.clearable != null
              ? elCol.elFormItem.clearable
              : formConfBak.clearable
          "
        />
        <el-autocomplete
          v-else-if="elCol.elFormItem.type == 'autocomplete'"
          v-model="model[elCol.elFormItem.prop]"
          :style="elCol.elFormItem.style"
          :placeholder="
            elCol.elFormItem.placeholder != null
              ? elCol.elFormItem.placeholder
              : '请输入' + elCol.elFormItem.label
          "
          :disabled="elCol.elFormItem.disabled"
          :maxlength="elCol.elFormItem.maxlength"
          :show-word-limit="elCol.elFormItem.showWordLimit"
          :autosize="elCol.elFormItem.autosize"
          :fetch-suggestions="querySearch"
          :trigger-on-focus="elCol.elFormItem.triggerOnFocus"
          :value-key="
            elCol.elFormItem.valueKey
              ? elCol.elFormItem.valueKey
              : formConf.autocompleteValueKey
              ? formConf.autocompleteValueKey
              : formConfBak.autocompleteValueKey
          "
          :clearable="
            elCol.elFormItem.clearable != null
              ? elCol.elFormItem.clearable
              : formConfBak.clearable
          "
          @select="select"
          @focus="focus(elCol)"
          @change="change"
          @blur="blur(elCol)"
        ></el-autocomplete>
        <slot v-else :name="elCol.elFormItem.type" :elCol="elCol"></slot>
      </el-form-item>
      <el-button
        v-for="(btnItem, btnIndex) in btnConf.buttons != null
          ? btnConf.buttons
          : btnConfBak.buttons"
        v-show="btnItem.show != null ? btnItem.show : btnConfBak.show"
        :key="'btn' + btnIndex"
        :type="btnItem.type"
        :size="btnItem.size != null ? btnItem.size : btnConfBak.size"
        :plain="btnItem.plain != null ? btnItem.plain : btnConfBak.plain"
        :round="btnItem.round != null ? btnItem.round : btnConfBak.round"
        :circle="btnItem.circle != null ? btnItem.circle : btnConfBak.circle"
        :loading="
          btnItem.loading != null ? btnItem.loading : btnConfBak.loading
        "
        :disabled="
          btnItem.disabled != null ? btnItem.disabled : btnConfBak.disabled
        "
        :icon="btnItem.icon != null ? btnItem.icon : btnConfBak.icon"
        :autofocus="
          btnItem.autofocus != null ? btnItem.autofocus : btnConfBak.autofocus
        "
        :native-type="
          btnItem.nativeType != null
            ? btnItem.nativeType
            : btnConfBak.nativeType
        "
        :style="btnItem.style"
        @click="btnClick(btnItem)"
      >
        {{ btnItem.name }}
      </el-button>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'MySearch',
  props: {
    model: {
      type: Object,
      required: true
    },
    layout: {
      type: Array,
      required: true
    },
    formConf: {
      type: Object,
      default() {
        return {}
      }
    },
    btnConf: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      formConfBak: {
        ref: 'form',
        size: 'small',
        labelWidth: '120px',
        labelSuffix: '：',
        inline: true,
        clearable: true,
        dateTime: {
          startPlaceholder: '开始日期',
          endPlaceholder: '结束日期',
          rangeSeparator: '至'
        },
        autocompleteValueKey: 'label'
      },
      btnConfBak: {
        plain: false,
        round: false,
        circle: false,
        loading: false,
        disabled: false,
        autofocus: false,
        nativeType: 'button',
        show: true,
        size: 'small',
        buttons: [
          { name: '查询', type: 'primary' },
          { name: '重置', callback: false, show: false }
        ]
      }
    }
  },
  created() {
    const buttons =
      this.btnConf.buttons != null
        ? this.btnConf.buttons
        : this.btnConfBak.buttons
    for (let i = 0; i < buttons.length; i++) {
      this.$set(buttons[i], 'loading', false)
    }
  },
  methods: {
    formValidate(...args) {
      this.$emit('validate', ...args)
    },
    change(...args) {
      this.$emit('change', ...args, this.activeElCol)
    },
    select(...args) {
      this.$emit('select', ...args, this.activeElCol)
    },
    focus(elCol) {
      this.activeElCol = elCol
      this.$emit('focus', this.activeElCol)
    },
    blur(elCol) {
      if (this.activeElCol.elFormItem.prop === elCol.elFormItem.prop) {
        this.activeElCol = null
        this.$emit('blur')
      }
    },
    querySearch(queryString, cb) {
      if (this.activeElCol.elFormItem.options == null) {
        this.activeElCol.elFormItem.options = []
      }
      const results = queryString
        ? this.activeElCol.elFormItem.options.filter(
            this.createFilter(queryString)
          )
        : this.activeElCol.elFormItem.options
      // 调用 callback 返回建议列表的数据
      cb(results)
    },
    createFilter(queryString) {
      return (restaurant) => {
        return (
          restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) ===
          0
        )
      }
    },
    btnClick(btnItem) {
      if (
        btnItem.name === '重置' &&
        btnItem.callback !== undefined &&
        btnItem.callback === false
      ) {
        const ref =
          this.formConf.ref != null ? this.formConf.ref : this.formConfBak.ref
        this.$refs[ref].resetFields()
      } else {
        this.$emit('btnClick', btnItem)
      }
    }
  }
}
</script>

<style scoped></style>
